package org.rabbitmq.rabbitextensions.listener;

import com.rabbitmq.client.Channel;
import org.rabbitmq.rabbitextensions.constant.Constants;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.UnsupportedEncodingException;

/**
 * 测试消息确认机制:none,auto,manual
 */
//@Component
public class AckListener {
    /**
     *none自动确认模式下:消息⼀旦投递给消费者, 不管消费者是否成功处理了消息,
     RabbitMQ 就会⾃动确认消息, 从RabbitMQ队列中移除消息. 如果消费者处理消息失败, 消息可能会丢失
     * @param message
     * @param channel
     * @throws UnsupportedEncodingException
     */
    @RabbitListener(queues = Constants.ACK_QUEUE)
    public void handlerMessage(Message message, Channel channel) throws UnsupportedEncodingException {
        System.out.printf("收到消息:%s ,deliverTag: %d \n",new String(message.getBody(),"UTF-8"),
                message.getMessageProperties().getDeliveryTag());
        System.out.println("处理业务逻辑");
        //none模式下,消息处理失败,但还是会被从消息消息队列中移除
//        int t = 3/0;
//        System.out.println("t="+t);
        System.out.println("处理完成");
    }
    /**
     * auto:默认:消费者在消息处理成功时 会⾃动确认消息, 但如果处理过程中抛出了异常,则不会确认消息.
     * @param message
     * @param channel
     * @throws UnsupportedEncodingException
     */
    @RabbitListener(queues = Constants.ACK_QUEUE)
    public void handlerMessage1(Message message, Channel channel) throws UnsupportedEncodingException {
        System.out.printf("收到消息:%s ,deliverTag: %d \n",new String(message.getBody(),"UTF-8"),
                message.getMessageProperties().getDeliveryTag());
        System.out.println("处理业务逻辑");
        //auto模式下,若接收消息时,抛出了异常,就不会自动处理消息,若设置未正常处理消息,自动将其加入到队列中,
        //就会重复加入,循环处理消息,循环保存,
        int t = 1/0;
        System.out.println("处理完成");
    }

    /**
     *
     *manual:手动确认模式:
     * ⼿动确认模式下, 消费者必须在成功处理消息后显式调⽤  basicAck  ⽅法来确认消息. 如果消
     * 息未被确认, RabbitMQ 会认为消息尚未被成功处理, 并且会在消费者可⽤时重新投递该消息, 这
     * 种模式提⾼了消息处理的可靠性, 因为即使消费者处理消息后失败, 消息也不会丢失, ⽽是可以被
     * 重新处理.
     * @param message
     * @param channel
     * @throws UnsupportedEncodingException
     */
    @RabbitListener(queues = Constants.ACK_QUEUE)
    public void handlerMessage2(Message message, Channel channel) throws IOException {
        long  deliveryTag = message.getMessageProperties().getDeliveryTag();
       try{
            System.out.printf("收到消息:%s ,deliverTag: %d \n",new String(message.getBody(),"UTF-8"),
                    message.getMessageProperties().getDeliveryTag());
            System.out.println("处理业务逻辑");
            int t = 1/0;
            System.out.println("处理完成");
            //肯定确认                      是否批量确认
            channel.basicAck(deliveryTag,false);
       }catch(Exception e){
        //否定确认:                      是否批量确认  是否重新入队
           channel.basicNack(deliveryTag,false,true);
       }
    }
}
